package com.lge.clock.test;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Instrumentation;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.widget.Adapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ListView;

import com.lge.clock.AlarmActivity;
import com.lge.clock.R;
import com.lge.clock.alarmclock.ALProvider;
import com.lge.clock.alarmclock.ALSettings;
import com.lge.clock.alarmclock.AlarmAlert;
import com.lge.clock.alarmclock.AlarmDeleteListActivity;
import com.lge.clock.alarmclock.Alarms;
import com.lge.inner_sui.widget.control.SUIDrumTimePicker;

public class AlarmActivityTest_sangkyeong extends ActivityInstrumentationTestCase2<AlarmActivity> {
	
	Instrumentation inst;	
	Activity currentActivity;
	private static final int DELETEALL_ID = Menu.FIRST+2;
	private static final int MULTISELECT_ID = Menu.FIRST+3;
	private static final int ACTIVITY_CHECK_INTERVAL = 5000;
	private static final String[] PROJECTION_1_STRINGS = new String[] { "_id",  "hour",  "minutes", "daysofweek",  "enabled", "widget_yn" };
	Instrumentation.ActivityMonitor monitor;
	private int numOfItems=0;
	public AlarmActivityTest_sangkyeong() {
		super("com.lge.clock", AlarmActivity.class);
	}

	protected void setUp() throws Exception {
		super.setUp();
		
		inst = getInstrumentation();
		IntentFilter filter = null;
		monitor = inst.addMonitor(filter, null, false);
		currentActivity = getActivity();
		
	}
	protected void tearDown() throws Exception {	
		
		currentActivity.finish();
		super.tearDown();
	}

	public void deleteAllTimeFromDatabase(){
		ContentResolver cr = currentActivity.getContentResolver();
		
		Cursor c;
		c = cr.query(ALProvider.CONTENT_ALARMS_URI, null, null, null, null);
		if (c.moveToFirst()) {
			cr.delete(ALProvider.CONTENT_ALARMS_URI, null, null);
		}
		c = cr.query(ALProvider.CONTENT_CALCU_URI, null, null, null, null);
		if (c.moveToFirst()) {
			cr.delete(ALProvider.CONTENT_CALCU_URI, null, null);
		}
	}
	public void insertTimeToDatabase(int mHour,int mMinute){
		ContentResolver cr = currentActivity.getContentResolver();
		
		int mDayOfWeek = 0;
		
		ContentValues cv = new ContentValues();
		cv.put("hour", 		mHour);
		cv.put("minutes", 		mMinute);     
		cv.put("daysofweek",   mDayOfWeek);
		cv.put("enabled", 	    "1"); 
		cv.put("stop",  	    ""); 

		ContentValues value = new ContentValues();
		value.put("hour", 		mHour);
		value.put("minutes", 		mMinute);     
		value.put("daysofweek",   mDayOfWeek);
		value.put("snooze",5);
		value.put("tone", "content://media/internal/audio/media/3" );
		value.put("vib",       "On");
		value.put("puzzle",    "Off");
		value.put("enabled", 	    "1" );         
		value.put("widget_yn", 	"N" );
		cr.insert(ALProvider.CONTENT_ALARMS_URI,	value);	

		int maxID = 0;

		String[] projection = new String[] { "max(_id) ID" };
		Cursor cc = null;
		try {
			cc = cr.query(Uri.parse(Alarms.CONTENT_ALARMS_URI_STRING.concat("?queryType=1")), projection, null, null, null);
			if (cc != null) {   //WBT fix td 207876
				if (cc.moveToFirst()) {  
					maxID = cc.getInt(0);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if ( cc != null )
				cc.close();
		}

		cv.put( "aid",    maxID);
		cv.put( "aindex", 0);
		cv.put( "status", "A");
		cr.insert(ALProvider.CONTENT_CALCU_URI, cv);
	}
	public void checkSequenceOfResult(){
		assertEquals(AlarmActivity.class.getName(), currentActivity.getClass().getName());
		Cursor cursorQuery = currentActivity.managedQuery(Uri.parse(Alarms.CONTENT_ALARMS_URI_STRING.concat("?queryType=1")), PROJECTION_1_STRINGS, null, null, "widget_yn desc, hour, minutes, _id");
		assertNotNull(cursorQuery);
		
		int hourIndex = cursorQuery.getColumnIndex("hour");
		int minutesIndex = cursorQuery.getColumnIndex("minutes");
		
		cursorQuery.moveToFirst();
		int hourA = cursorQuery.getInt(hourIndex);
		int minuteA = cursorQuery.getInt(minutesIndex);
		assertEquals(0, hourA);
		assertEquals(0, minuteA);
		
		cursorQuery.moveToNext();
		hourA = cursorQuery.getInt(hourIndex);
		minuteA = cursorQuery.getInt(minutesIndex);
		assertEquals(11, hourA);
		assertEquals(59, minuteA);
		
		cursorQuery.moveToNext();
		hourA = cursorQuery.getInt(hourIndex);
		minuteA = cursorQuery.getInt(minutesIndex);
		assertEquals(12, hourA);
		assertEquals(0, minuteA);
		
		cursorQuery.moveToNext();
		hourA = cursorQuery.getInt(hourIndex);
		minuteA = cursorQuery.getInt(minutesIndex);
		assertEquals(23, hourA);
		assertEquals(59, minuteA);
		
		
//		int hourA = cursorQuery.getInt(hourIndex);
//		int minuteA = cursorQuery.getInt(minutesIndex);
//		
//		while(cursorQuery.moveToNext()){
//			int hourB = cursorQuery.getInt(hourIndex);
//			int minuteB = cursorQuery.getInt(minutesIndex);
//			
//			int timeA = hourA*60+minuteA;
//			int timeB = hourB*60 + minuteB;
//			
//			assertTrue(timeA<timeB);
//		}
//		
//		
//		LinearLayout row = (LinearLayout) lv.getChildAt(1);
//		FrameLayout fl = (FrameLayout)row.findViewById(R.id.rowLayout);
//		assertNotNull(fl);
//		int targetAHour = Integer.parseInt(((TextView)fl.findViewById(R.id.hour)).getText().toString());
//		int targetAMinute = Integer.parseInt(((TextView)fl.findViewById(R.id.minutes)).getText().toString());
//
//		for(int i=1;i<3;i++){
//			row = (LinearLayout) lv.getChildAt(1+i);
//			fl = (FrameLayout)row.findViewById(R.id.rowLayout);
//			assertNotNull(fl);
//			int targetBHour = Integer.parseInt(((TextView)fl.findViewById(R.id.hour)).getText().toString());
//			int targetBMinute = Integer.parseInt(((TextView)fl.findViewById(R.id.minutes)).getText().toString());
//			Log.i("ALARMTEST","compare "+targetAHour+":"+targetAMinute+" with "+targetBHour+":"+targetBMinute);
//			int timeA = targetAHour*60 + targetAMinute;
//			int timeB = targetBHour*60 + targetBMinute;
//			assertTrue(timeA<timeB);
//			
//			targetAHour = targetBHour;
//			targetAMinute = targetBMinute;
//		}
	}
	public void testDESCOrderedInput() throws Exception{
		
		
		int [][]timeExample = new int[4][2];
		timeExample[0][0] = 00; timeExample[0][1] = 00; //12:00 AM
		timeExample[1][0] = 11; timeExample[1][1] = 59; //11:59 AM
		timeExample[2][0] = 12; timeExample[2][1] = 00; //12:00 PM
		timeExample[3][0] = 23; timeExample[3][1] = 59; //11:59 PM
		
		List<Integer> sequence = new ArrayList<Integer>();
		sequence.add(0); sequence.add(1); sequence.add(2); sequence.add(3);
		
		Collections.reverse(sequence);
		
		deleteAllTimeFromDatabase();
		for(int i : sequence){
			Log.i("ALARMTEST",""+i);
			insertTimeToDatabase(timeExample[i][0],timeExample[i][1]);
		}
				
		checkSequenceOfResult();
		
	}
	public void testShuffledOrderedInput() throws Exception{
		
		int [][]timeExample = new int[4][2];
		timeExample[0][0] = 00; timeExample[0][1] = 00; //12:00 AM
		timeExample[1][0] = 11; timeExample[1][1] = 59; //11:59 AM
		timeExample[2][0] = 12; timeExample[2][1] = 00; //12:00 PM
		timeExample[3][0] = 23; timeExample[3][1] = 59; //11:59 PM
		
		List<Integer> sequence = new ArrayList<Integer>();
		sequence.add(0); sequence.add(1); sequence.add(2); sequence.add(3);
		
		for(int j=0;j<10;j++){
		
			deleteAllTimeFromDatabase();
			
			Collections.shuffle(sequence);
			
			for(int i : sequence){
				Log.i("ALARMTEST",""+i);
				insertTimeToDatabase(timeExample[i][0],timeExample[i][1]);
			}
					
			checkSequenceOfResult();
		}
		
	}
	public void testASCOrderedInput() throws Exception{
		
		int [][]timeExample = new int[4][2];
		timeExample[0][0] = 00; timeExample[0][1] = 00; //12:00 AM
		timeExample[1][0] = 11; timeExample[1][1] = 59; //11:59 AM
		timeExample[2][0] = 12; timeExample[2][1] = 00; //12:00 PM
		timeExample[3][0] = 23; timeExample[3][1] = 59; //11:59 PM
		
		List<Integer> sequence = new ArrayList<Integer>();
		sequence.add(0); sequence.add(1); sequence.add(2); sequence.add(3);
		
		deleteAllTimeFromDatabase();
		
		for(int i : sequence){
			Log.i("ALARMTEST",""+i);
			insertTimeToDatabase(timeExample[i][0],timeExample[i][1]);
		}
				
		checkSequenceOfResult();
		
	}
//	public void testDeleteAlarm()throws Exception{
//		deleteAllAlarm();
//		addTenAlarm();
//		inst.invokeMenuActionSync(currentActivity, MULTISELECT_ID, 0);
//		inst.waitForIdleSync();
//		currentActivity = monitor.getLastActivity();
//		assertEquals(AlarmDeleteListActivity.class.getName(),currentActivity.getClass().getName());
//		
//		currentActivity.runOnUiThread(new Runnable(){
//			@Override
//			public void run() {
//				
//				ListView lv = (ListView)currentActivity.findViewById(R.id.alarms_list);
//				numOfItems = lv.getCount();
//				View chileView = lv.getChildAt(0);
//				CheckedTextView checkView = (CheckedTextView)chileView.findViewById(R.id.checkboxView01);
//				checkView.setChecked(true);
//				Button delBtn = (Button) currentActivity.findViewById(R.id.deleteButton);
//				KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER); 
//				KeyEvent event1 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER);
//				delBtn.dispatchKeyEvent(event);
//				delBtn.dispatchKeyEvent(event1);
//			}});
//		inst.waitForIdleSync();
//		currentActivity = monitor.getLastActivity();
//		currentActivity.runOnUiThread(new Runnable(){
//			@Override
//			public void run() {
//				AlertDialog deleteDialog = ((AlarmDeleteListActivity)currentActivity).getDeleteAllYnDialog();
//				Button positiveBtn = deleteDialog.getButton(AlertDialog.BUTTON_POSITIVE);
//				KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER); 
//				KeyEvent event1 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER);
//				positiveBtn.dispatchKeyEvent(event);
//				positiveBtn.dispatchKeyEvent(event1);
//				ListView lv = (ListView)currentActivity.findViewById(R.id.alarms_list);
//				assertEquals(numOfItems,lv.getCount());
//			}});
//				
//	}
	
	
	public void clickViewById(int id){
		View view = currentActivity.findViewById(id);
		TouchUtils.clickView(this,view);
		inst.waitForIdleSync();
	}
	
	public void testGoToAlarmSettingActivity() throws Exception{
		clickViewById(R.id.noListaddButton);
		currentActivity = monitor.getLastActivity();
		assertEquals(ALSettings.class.getName(),currentActivity.getClass().getName());
	}
	
	public SUIDrumTimePicker getTimePicker(){
		boolean is24HourFormatType = DateFormat.is24HourFormat(currentActivity);
		SUIDrumTimePicker mTimePicker;
		if(is24HourFormatType) {
			mTimePicker = (SUIDrumTimePicker)currentActivity.findViewById(R.id.timepicker_24);
		} else {
			mTimePicker = (SUIDrumTimePicker)currentActivity.findViewById(R.id.timepicker_12);
		}
		return mTimePicker;
	}
	
	public void testCurrentTimeEqualWithSUIDrumTimePicker() throws Exception{
		int hour;
		int minute;
		
		testGoToAlarmSettingActivity();
		SUIDrumTimePicker mTimePicker = getTimePicker();
		

		Calendar mCalendar = Calendar.getInstance();
		hour = mCalendar.get(Calendar.HOUR_OF_DAY);
		minute = mCalendar.get(Calendar.MINUTE);

		assertEquals(hour, mTimePicker.getCurrentHour());
		assertEquals(minute, mTimePicker.getCurrentMinute());
		
	}
	
	public void testHonkAlarm()throws Exception{
		deleteAllTimeFromDatabase();
		testAlarmSettingAfterOneMinute();
		assertAlarmAlert(1, ACTIVITY_CHECK_INTERVAL);
	}

	public void assertAlarmAlert(int duration_minutes, int activityCheckInterval_ms)throws Exception{
        int duration_ms = (duration_minutes*60+5)/(activityCheckInterval_ms/1000);
		for(int i = 0; i < duration_ms; i ++){
			currentActivity = monitor.getLastActivity();
			if(!AlarmAlert.class.getName().equals(currentActivity.getClass().getName())){
				Thread.sleep(activityCheckInterval_ms);
				continue;
			} else {
                return;
            }
		}	
        fail("Expected AlarmAlert but no AlarmAlert");
	}

	public void assertNoAlarmAlert(int duration_minutes, int activityCheckInterval_ms)throws Exception{
        int duration_ms = duration_minutes*60*1000+activityCheckInterval_ms;
		for(int i = 0; i < duration_ms; i += activityCheckInterval_ms){
			currentActivity = monitor.getLastActivity();
            assertNotSame(AlarmAlert.class, currentActivity.getClass());
            Thread.sleep(activityCheckInterval_ms);
		}	
	}

	public void testDefaultSnooze() throws Exception{
		testHonkAlarm();
		clickViewById(R.id.snoozebutton);
		assertAlarmAlert(5, ACTIVITY_CHECK_INTERVAL);
	}
	
	public void testStopSnooze()throws Exception{
		testHonkAlarm();
		clickViewById(R.id.stopbutton);
		currentActivity = monitor.getLastActivity();
		assertEquals(AlarmActivity.class.getName(),currentActivity.getClass().getName());
	}
	
	public void testAlarmSettingAfterOneMinute() throws Exception{
		int hour;
		int minute;
		testGoToAlarmSettingActivity();
		assertEquals(ALSettings.class.getName(),currentActivity.getClass().getName());
		SUIDrumTimePicker mTimePicker = getTimePicker();		
		Calendar mCalendar = Calendar.getInstance();
		minute = mCalendar.get(Calendar.MINUTE);
		
		int start_Y = mTimePicker.getTop()+mTimePicker.getHeight();
		int point_X = mTimePicker.getLeft()+mTimePicker.getWidth()-150;
		long eventTime = SystemClock.uptimeMillis();
		
		boolean is24HourFormatType = DateFormat.is24HourFormat(currentActivity);
		
		if(is24HourFormatType)
			TouchUtils.drag(this, point_X, point_X, start_Y, start_Y-35, 35);
		else
			TouchUtils.drag(this, point_X, point_X, start_Y, start_Y-35, 35);
		
		inst.waitForIdleSync();
		
		if(minute == 59){
			start_Y = mTimePicker.getTop()+mTimePicker.getHeight();
			point_X = mTimePicker.getLeft()+50;
			eventTime = SystemClock.uptimeMillis();
			
			TouchUtils.drag(this, point_X, point_X, start_Y, start_Y-35, 35);
			inst.waitForIdleSync();
			minute = -1;
		}
		
		assertEquals(minute+1, mTimePicker.getCurrentMinute());
		
		Button saveBtn = (Button)(((ALSettings)currentActivity).findViewById(R.id.saveButton));
		TouchUtils.clickView(this,saveBtn);	
		inst.waitForIdleSync();
		currentActivity = monitor.getLastActivity();
		assertEquals(AlarmActivity.class.getName(),currentActivity.getClass().getName());
		
	}

    /**
     * on/off icon 은 동작해야 한다.
     * off icon 클릭
     */

	public void testNoHonkAlarmAfterClickingOffIcon() throws Exception{
		deleteAllTimeFromDatabase();
		testAlarmSettingAfterOneMinute();
		clickViewById(R.id.abcd);
		assertNoAlarmAlert(1, ACTIVITY_CHECK_INTERVAL);
	}

    /**
     * on/off icon 은 동작해야 한다.
     * off icon 클릭한 후 on icon 클릭
     */

	public void testHonkAlarmAfterClickingOffIconTwice() throws Exception{
		deleteAllTimeFromDatabase();
		testAlarmSettingAfterOneMinute();
		clickViewById(R.id.abcd);
		clickViewById(R.id.abcd);
		assertAlarmAlert(1, ACTIVITY_CHECK_INTERVAL);
	}

    /**
     * Set alarm 화면에서 Save버튼을 누르면 알람이 저장되고 Default는 알람 On이다. 
     * default로 on인가.
     */

	public void testHonkAlarmAfterAdd() throws Exception{
		deleteAllTimeFromDatabase();
		testAlarmSettingAfterOneMinute();
		assertAlarmAlert(1, ACTIVITY_CHECK_INTERVAL);
	}

    /**
     * Set alarm 화면에서 Save버튼을 누르면 알람이 저장되고 Default는 알람 On이다. 
     * 알람이 저장되는가.
     */

    public void testSaveAlarmAfterAdd() throws Exception {
        fail("테스트 미구현");
    }

}
